import axios from 'axios'
import store from '@/store'
import router from '@/router'

// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
})

service.interceptors.request.use(
  config => {
    const token = store.getters.token
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 响应拦截器
// 知识点: axios 内部的处理机制
// 1. http状态码为 2xx 3xx 就会给 Promise 对象位置,返回成功的结果(resolve())
// 2. http状态码为 4xx 5xx 就会给 Promise 对象位置,返回成功的结果(reject())
// 如果想做一些操作,可以在 axios 的相应拦截器,自己处理返回结果
// 补充 http 状态码,由本次请求后 后端进行设置返回
service.interceptors.response.use(
  response => { // http 2xx 3xx 进入到这里
    // 本项目成功/失败都是2xx 响应状态码 都进这里 所以需要自己字段判断
    const { success, message } = response.data
    if (success === false) { // 失败
      return Promise.reject(new Error(message))
    } else { // 成功
      // 返回 response => 返回的还是 axios 处理的结果(逻辑那边得 .data.data)拿到后台会返回的值
      // 返回 response.data => 返回的就是后台返回的相应对象(逻辑那边拿到的真正的数据.data)拿到返回值
      return response.data // 特殊 返回到的是 axios 调用在原地留下的Promise 对象位置( 在 await 后面 )
    }
  },
  error => { // http 4xx 5xx 进入这里
    // console.dir(error)
    // 身份过期后台双重返回401和逻辑状态码
    if (error.response.data.code === 10002) { // 身份过期
      store.commit('user/REMOVE_TOKEN') // 内部删除本地 cookie 里 token
      store.commit('user/RESET_STATE')
      router.replace(`/login?redirect=${encodeURIComponent(this.$route.fullPath)}`)
    }
    return Promise.reject(error) // 相当于 reject(error)
  }
)

export default service
